﻿using System;
using System.Text;
using System.Collections.Generic;
using DDotNet.ORM.DataFactory;
using DDotNet.ORM.DataFactory.DirectAccess;
using DDotNet.ORM.DataFactory.DirectAccess.Enum;
using DDotNet.ORM.DataFactory.DirectAccess.QueryParameter;
using DDotNet.ORM.DataFactory.Enum;
using DDotNet.ORM.DataFactory.Interface;
using GenericTests.Entities;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace GenericTests
{
    /// <summary>
    /// Summary description for DataBaseFactory
    /// </summary>
    [TestClass]
    public class SingleEntity_DataBaseFactory
    {
        public SingleEntity_DataBaseFactory()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void SelectAll()
        {
            // Cria Objetos
            UserCollection users = new UserCollection();
            ICrudFactory factory;
            DirectAccessQueryFactory directAccessQueryFactory;

            using (factory = new CRUDFactory())
            {
                directAccessQueryFactory = new DirectAccessQueryFactory(factory);
                users.Fill(directAccessQueryFactory.SelectAll(typeof(User)));
            }
        }

        [TestMethod]
        public void SelectCount()
        {
            // Cria Objetos
            ICrudFactory factory;
            DirectAccessQueryFactory directAccessQueryFactory;

            using (factory = new CRUDFactory())
            {
                directAccessQueryFactory = new DirectAccessQueryFactory(factory);
                directAccessQueryFactory.SelectAll(typeof(User));
            }
        }

        [TestMethod()]
        public void DeleteUser()
        {
            // Cria Objetos
            User newUser = new User();
            User oldUser;
            ICrudFactory factory;
            DirectAccessQueryFactory directAccessQueryFactory;

            // Seta Valores
            newUser.Login = "ABCDEF";
            newUser.Password = "654987-*/";
            newUser.FullName = "abcdefghijklmnopqrstuvxz!@#$%¨&*()";
            
            try
            {
                using (factory = new CRUDFactory())
                {
                    directAccessQueryFactory = new DirectAccessQueryFactory(factory);
                    
                    // Atualiza (Insere)
                    factory.Update(newUser);
                
                    // Marca para Exclusão
                    newUser.MarkDeleted();
                
                    // Atualiza (Exclui)
                    factory.Update(newUser);

                    // Recupera e Confere
                    oldUser =
                        (User)directAccessQueryFactory.SelectItemByQuery(typeof(User),
                                                        new GenericQueryParameter("IDUser", GenericComparerMode.Equals,
                                                                                  newUser.IDUser));
                
                }

                // Verifica se não Achou (Se Exclui, não acha)
                Assert.IsNull(oldUser, "Exclusão não apagou os dados");
            }
            catch (Exception e)
            {
                Assert.Fail(e.InnerException.Message);
            }
        }
        
        [TestMethod()]
        public void DeleteAllUsers()
        {
            // Cria Objetos
            ICrudFactory factory;
            DirectAccessQueryFactory directAccessQueryFactory;
            
            try
            {
                using (factory = new CRUDFactory())
                {
                    directAccessQueryFactory = new DirectAccessQueryFactory(factory);

                    // Atualiza (Insere)
                    factory.DeleteAll(typeof(User));

                    // Verifica se Apagou Todos
                    Assert.IsTrue(directAccessQueryFactory.SelectCount(typeof(User)) == 0, "O Comando DeleteALL não Exclui Todos os Usuários");
                }
            }
            catch (Exception e)
            {
                Assert.Fail(e.Message);
            }
        }

        [TestMethod()]
        public void UpdateUser()
        {
            // Cria Objetos
            User newUser = new User();
            User oldUser;
            ICrudFactory factory;
            DirectAccessQueryFactory directAccessQueryFactory;
            
            // Seta Valores
            newUser.Login = "ABCDEF";
            newUser.Password = "654987-*/";
            newUser.FullName = "abcdefghijklmnopqrstuvxz!@#$%¨&*()";

            using (factory = new CRUDFactory())
            {
                directAccessQueryFactory = new DirectAccessQueryFactory(factory);
                
                // Atualiza (Insere)
                factory.Update(newUser);
                
                
                // Muda os Valores
                newUser.Login = "KKKKKKK";
                
                // Atualiza (Update)
                factory.Update(newUser);
                
                
                // Recupera e Confere
                oldUser =
                    (User) directAccessQueryFactory.SelectItemByQuery(typeof (User),
                                                     new GenericQueryParameter("IDUser", GenericComparerMode.Equals,
                                                                               newUser.IDUser));

            }

            // Valida o Login
            Assert.AreEqual(oldUser.Login, newUser.Login, "Atualização não gravou os dados");
        }

        [TestMethod()]
        public void InsertUser()
        {
            // Cria Objetos
            User newUser = new User();
            ICrudFactory factory;
            
            // Coloca Valores
            newUser.Login = "ABCDEF";
            newUser.Password = "654987-*/";
            newUser.FullName = "abcdefghijklmnopqrstuvxz!@#$%¨&*()";
            
            try
            {
                using (factory = new CRUDFactory())
                {
                    // Atualiza
                    factory.Update(newUser);
                }

                // Verifica se Trouxe um ID
                Assert.IsTrue(newUser.IDUser > 0, "Não foi possível inserir ou não foi possível recuperar o ID Identity");
            }
            catch (Exception e)
            {
                Assert.Fail(e.Message);
            }
        }
    }
}
